/*
 * mkdir.c
 *
 *  Created on: Feb 14, 2011
 *      Author: Rahul
 */
#include "superblock.h"
#include "global.h"
#include "inode.h"
#include "directoryentry.h"
#include "v6fscommands.h"

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>

int mkdir(int inodeblocks, char *directoryname)                  /*inodeblocks=total # of blocks dedicated to store inode #'s*/
{
struct inode inode;
int rvalue,i;
unsigned short position;
char buffer[14], eof[4]="000";
time_t presenttime;
char eofindicator[4]="EOF";
struct directoryentry rdirectoryentry;
struct tm *currenttime;
presenttime=time(0);                               /*This gives current time in secs*/
currenttime=localtime(&presenttime);               /*This converts secs into hrs and mins and returns a pointer to a 'struct tm'*/

/*To open the FS file*/
if((fsfd=open("ffs", O_RDWR))<0)
	{
		printf("ERROR in mkdir: fsfd<0\n");
		exit(1);
	}

/*Check if the inodes are available.*/

if ((iptr==100)&&(superblock.ninode==0))                /*If iptr goes to 100 fill your inode array in the SB.*/
	{
		printf("ERROR:The number of inodes in the superblock ");
		exit(1);
	}

/*Write the necessary parameters to the inode.*/
memset(&inode, 0, sizeof(struct inode));

inode.flags=13180;
inode.nlinks=0;
inode.uid=1;
inode.gid=1;
inode.size0=0;                           /*size0 and size1 gives the size of the file itself.*/
inode.size1=BLOCK_SIZE;
/*Each directory has only 1 block of memory (I mean 512 Bytes). Therfore only 32 entries in 1 directory.*/

/*Check to see if there are any free data blocks left in the superblock.*/
superblock.nfree--;
if (superblock.free[superblock.nfree]==0)
	{
		printf("ERROR:No more data blocks left\n");
		exit(1);
	}
else
		inode.addr[0]=(2+inodeblocks+superblock.free[superblock.nfree])*BLOCK_SIZE;     /*2 for BS and SB and 1 for SB data block.*/

inode.actime[0]=currenttime->tm_hour;
inode.actime[1]=currenttime->tm_min;
inode.modtime[0]=currenttime->tm_hour;
inode.modtime[1]=currenttime->tm_min;

rvalue=lseek(fsfd, ((BLOCK_SIZE*2)+(32*superblock.inode[iptr])), SEEK_SET);  /*superblock.inode[iptr] contains the address of the next free inode*/

if ((write(fsfd, &inode, sizeof(struct inode)))!=sizeof(struct inode))
	{
		printf("ERROR in mkdir:inode info not written\n");
		exit(1);
	}
superblock.ninode--;        /*The number free inodes IN THE SUPERBLOCK is reduced by 1*/
numberofinodesrem--;        /*The number of inodes now is (inodeblocks*16)-1*/
numofdatablocksrem--;       /*Total # of data blocks remaining now.*/


/*Superblock modified. Write to Superblock.*/
rvalue=lseek(fsfd, BLOCK_SIZE, SEEK_SET);

if ((write(fsfd, &superblock, sizeof(struct superblock)))!=sizeof(struct superblock))
	{
		printf("ERROR in mkdir:Superblock not written\n");
		exit(1);
	}

/*Create directory entries '.' and '..'*/
rvalue=lseek(fsfd, inode.addr[0], SEEK_SET);

sprintf(buffer, ".");
strcpy(rdirectoryentry.filename, buffer);
rdirectoryentry.inodenumber=iptr;

if ((write(fsfd, &rdirectoryentry.inodenumber, sizeof(unsigned short)))!=sizeof(unsigned short))
	{
		printf("ERROR in mkdir:inode number not written.\n");
		exit(1);
	}
if ((write(fsfd, rdirectoryentry.filename, sizeof(rdirectoryentry.filename)))!=sizeof(rdirectoryentry.filename))
	{
		printf("ERROR in mkdir:filename not written.\n");
		exit(1);
	}

sprintf(buffer, "..");
strcpy(rdirectoryentry.filename, buffer);
rdirectoryentry.inodenumber=cparentinode;

if ((write(fsfd, &rdirectoryentry.inodenumber, sizeof(unsigned short)))!=sizeof(unsigned short))
	{
		printf("ERROR in mkdir:inode number not written.\n");
		exit(1);
	}
if ((write(fsfd, rdirectoryentry.filename, sizeof(rdirectoryentry.filename)))!=sizeof(rdirectoryentry.filename))
	{
		printf("ERROR in mkdir:filename not written.\n");
		exit(1);
	}
if ((write(fsfd, eofindicator, 4))!=4)
	{
		printf("ERROR in mkdir:EOF indicator not written.\n");
		exit(1);
	}

/*So, now you've created a new directory. Make an entry for this directory in it's parent directory.*/

rvalue=lseek(fsfd, ((BLOCK_SIZE*2)+(32*cparentinode)+7), SEEK_SET);
/*You've reached the parent inode of this directory you created.'+7' actually moves to the address
part of the inode which contains the address of the data block of the parent directory.*/

read(fsfd, &position, sizeof(unsigned short));
/*position gives the address of the data block.*/
position=position+32;             /*Move by extra 32 bytes to skip the parent and the current dir info.*/
rvalue=lseek(fsfd, position, SEEK_SET);
for(i=0;i<32;i++)
{
read(fsfd, eof, 4);
if(!strcmp(eof,eofindicator))
	break;
position=position+16;
rvalue=lseek(fsfd, position, SEEK_SET);
}

rvalue=lseek(fsfd, position, SEEK_SET); /*Goto that position where you need to make an entry.*/
rdirectoryentry.inodenumber=iptr;
//rdirectoryentry.filename=directoryname;

if ((write(fsfd, &rdirectoryentry.inodenumber, sizeof(unsigned short)))!=sizeof(unsigned short))
	{
		printf("ERROR in mkdir:inode number of the directory created not written.\n");
		exit(1);
	}
if ((write(fsfd, directoryname, sizeof(rdirectoryentry.filename)))!=sizeof(rdirectoryentry.filename))
	{
		printf("ERROR in mkdir:filename of the directory created not written.\n");
		exit(1);
	}
if ((write(fsfd, eofindicator, 4))!=4)
	{
		printf("ERROR in mkdir:EOF indicator not written back to the parent directory.\n");
		exit(1);
	}

printf("Directory Created-%s\n", directoryname);

iptr++;      								/*Next available inode number is iptr.*/
close(fsfd);

return 1;
}



